home *** CD-ROM | disk | FTP | other *** search
/ Nebula 1 / Nebula One.iso / Internet / Misc / ytalk / Source / ytalkd.c < prev   
Encoding:
C/C++ Source or Header  |  1995-06-12  |  4.1 KB  |  205 lines

  1. /* ytalkd.c - YTalk pass-thru daemon */
  2.  
  3. /*               NOTICE
  4.  *
  5.  * Copyright (c) 1990 Britt Yenne.  All rights reserved.
  6.  * 
  7.  * This software is provided AS-IS.  The author gives no warranty,
  8.  * real or assumed, and takes no responsibility whatsoever for any 
  9.  * use or misuse of this software, or any damage created by its use
  10.  * or misuse.
  11.  * 
  12.  * This software may be freely copied and distributed provided that
  13.  * no part of this NOTICE is deleted or edited in any manner.
  14.  * 
  15.  */
  16.  
  17. /* Mail comments or questions to yenne@ccwf.cc.utexas.edu */
  18.  
  19. #include "ytalk.h"
  20. #include <sys/time.h>
  21. #include <netdb.h>
  22. #include <pwd.h>
  23. #include <stdio.h>
  24. #include <sys/ioctl.h>
  25. #include <sys/file.h>
  26.  
  27. struct sockaddr_in bsd_sock;    /* for communicating udp with talk daemon */
  28. struct sockaddr_in bsd42_sock;    /* for communicating udp with talk daemon */
  29. struct in_addr myaddr;        /* caller's machine address */
  30. char myhost[100];        /* caller's machine hostname */
  31. short bsd_daemon = 0;        /* udp talk daemon port number */
  32. short bsd42_daemon = 0;        /* udp talk daemon version >4.2 */
  33. int bsd_fd, bsd42_fd;        /* socket descriptors */
  34.  
  35. char errstr[100];
  36. extern int errno;
  37. rcpack rc;
  38.  
  39. main(argc, argv)
  40. char **argv;
  41. {
  42.     int fd;
  43.  
  44.     if((fd = open("/dev/tty", O_RDWR)) >= 0)
  45.     {
  46.     ioctl(fd, TIOCNOTTY);
  47.     close(fd);
  48.     }
  49.     close(0);
  50.     close(1);
  51.     close(2);
  52.     if(fork())
  53.     exit(0);
  54.  
  55.     init_socks();    /* Initialize sockets */
  56.     for(;;)
  57.     {
  58.     readit();
  59.     sendit(myhost);
  60.     }
  61. }
  62.  
  63. /* Initialize sockets and message parameters.
  64.  */
  65. init_socks()
  66. {
  67.     struct hostent *host;
  68.     struct servent *serv;
  69.     struct passwd *pw;
  70.  
  71.     if((serv = getservbyname("talk", "udp")) == 0)
  72.     {
  73.     perror("Talk server not found");
  74.     exit(2);
  75.     }
  76.     bsd_daemon = serv->s_port;
  77.  
  78.     if((serv = getservbyname("ntalk", "udp")) != 0)
  79.     bsd42_daemon = serv->s_port;
  80.  
  81.     gethostname(myhost, 100);
  82.     if((host = (struct hostent *) gethostbyname(myhost)) == 0)
  83.     {
  84.     sprintf(errstr, "Unknown host: %s", myhost);
  85.     panic(errstr);
  86.     yytalkabort(5);
  87.     }
  88.     bcopy(host->h_addr, &myaddr, host->h_length);
  89.     strcpy(myhost, host->h_name);
  90.  
  91.     bsd_fd = init_dgram(&bsd_sock, YTPORT);
  92.     bsd42_fd = init_dgram(&bsd42_sock, 0);
  93. }
  94.  
  95. /* readit() reads a packet from the input datagram socket.
  96.  */
  97. readit()
  98. {
  99.     int n;
  100.  
  101.     do
  102.     {
  103.     if((n = recv(bsd_fd, &rc, sizeof(rc), 0)) != sizeof(rc))
  104.     {
  105.         if (errno == EINTR)
  106.         continue;
  107.         panic("recv failed");
  108.         continue;
  109.     }
  110.     } while(n <= 0);
  111.  
  112.     return n;
  113. }
  114.  
  115. /* sendit() then transmits to the other daemons.
  116.  */
  117. sendit(hostname)
  118. char *hostname;
  119. {
  120.     int n;
  121.     struct hostent *host;
  122.     struct sockaddr_in daemon;
  123.  
  124.     if((host = (struct hostent *) gethostbyname(hostname)) == 0)
  125.     {
  126.     sprintf(errstr, "Unknown host: %s", hostname);
  127.     panic(errstr);
  128.     return -1;
  129.     }
  130.  
  131.     if(rc.type)
  132.     {
  133.     daemon.sin_addr.s_addr = ((struct in_addr *) (host->h_addr))->s_addr;
  134.  
  135.     if(rc.type == 1)
  136.         daemon.sin_port = bsd_daemon;
  137.     else if(rc.type == 2)
  138.         daemon.sin_port = bsd42_daemon;
  139.     else
  140.     {
  141.         sprintf(errstr, "Unkown daemon type: %d", rc.type);
  142.         panic(errstr);
  143.         return -1;
  144.     }
  145.     }
  146.     else
  147.     bcopy(rc.buf, &daemon, sizeof(daemon));
  148.     daemon.sin_family = AF_INET;
  149.  
  150.     if(daemon.sin_port == 0)
  151.     return 0;
  152.  
  153.     do
  154.     {
  155.     n = sendto(bsd_fd, rc.buf, rc.length, 0, &daemon, sizeof(daemon));
  156.     if (n != rc.length)
  157.     {
  158.         if (errno == EINTR)    /* interrupted by some stray signal */
  159.         continue;
  160.         panic("Cannot write to talk daemon");
  161.         return -1;
  162.     }
  163.     } while(n != rc.length);
  164.  
  165.     return 0;
  166. }
  167.  
  168. /* Create a datagram socket.
  169.  */
  170. init_dgram(sock, port)
  171. struct sockaddr_in *sock;
  172. short port;
  173. {
  174.     int fd, socklen;
  175.  
  176.     sock->sin_family = AF_INET;
  177.     sock->sin_addr.s_addr = INADDR_ANY;
  178.     sock->sin_port = port;
  179.     if((fd = socket(AF_INET, SOCK_DGRAM, 0)) == -1)
  180.     {
  181.     perror("Cannot open DGRAM socket");
  182.     exit(2);
  183.     }
  184.     if(bind(fd, sock, sizeof(struct sockaddr_in), 0) != 0)
  185.     {
  186.     perror("Cannot bind DGRAM socket");
  187.     exit(2);
  188.     }
  189.     socklen = sizeof(struct sockaddr_in);
  190.     if(getsockname(fd, sock, &socklen) == -1)
  191.     {
  192.     perror("Cannot read DGRAM socket address");
  193.     exit(2);
  194.     }
  195.     sock->sin_addr = myaddr;
  196.     return fd;
  197. }
  198.  
  199. panic(str)
  200. char *str;
  201. {
  202.     fprintf(stderr, "%s\n", str);
  203.     return;
  204. }
  205.